<template>
  <q-page padding>
    <div class="text-h5 q-ma-md">
      提交竞赛成果
    </div>
    <div class="q-pa-md">
    <q-stepper
      v-model="step"
      vertical
      color="primary"
      animated
      flat
    >
      <q-step
        :name="1"
        title="材料上传"
        icon="settings"
        :done="step > 1"
      >
        <q-form class="row q-gutter-md" ref="form1">
          <q-select
            filled
            v-model="form.collectcate"
            use-input
            input-debounce="0"
            label="竞赛名称（支持搜索）"
            :options="options"
            @filter="filterFn"
            :rules="[val => !!val.pk]"
            behavior="dialog"
            class="col-12 col-md-4"
          >
          <!-- 现在我们想设置其选择的内容和展示的内容不同 -->
            <template v-slot:selected>
              <div v-if="form.collectcate">
                {{ form.collectcate.cate.name }}
              </div>
            </template>
            <template v-slot:option="scope">
              <q-item v-bind="scope.itemProps">
                <q-item-section>
                  <q-item-label>{{ scope.opt.cate.name }}</q-item-label>
                </q-item-section>
              </q-item>
            </template>
            <template v-slot:no-option>
              <q-item>
                <q-item-section class="text-grey">
                  暂无该竞赛，请向管理员反馈。
                </q-item-section>
              </q-item>
            </template>
          </q-select>

          <q-select filled v-model="form.level" v-if="form.collectcate.cate.collect_part === 'level'" :options="form.collectcate.cate.levels" label="获奖等级" class="col-12 col-md-3" >
            <template v-slot:selected>
              <div v-if="form.level">
                {{ form.level.name }}
              </div>
            </template>
            <template v-slot:option="scope">
              <q-item v-bind="scope.itemProps">
                <q-item-section>
                  <q-item-label>{{ scope.opt.name }}</q-item-label>
                </q-item-section>
              </q-item>
            </template>
          </q-select>

          <q-input filled v-model="form.date" mask="date" :rules="['date']" placeholder="获奖时间（点击右侧选择）" class="col-12 col-md-3">
            <template v-slot:append>
              <q-icon name="event" class="cursor-pointer">
                <q-popup-proxy ref="qDateProxy" transition-show="scale" transition-hide="scale">
                  <q-date mask="YYYY/MM/DD" v-model="form.date">
                    <div class="row items-center justify-end">
                      <q-btn v-close-popup label="Close" color="primary" flat />
                    </div>
                  </q-date>
                </q-popup-proxy>
              </q-icon>
            </template>
          </q-input>

          <q-input filled v-model="form.name" placeholder="项目名称" :rules="[val => !!val]" class="col-12 col-md-3" v-if="form.collectcate.cate.collect_part === 'name'"/>
          <q-input filled v-model="form.score" placeholder="竞赛成绩" :rules="[val => val > 0]" class="col-12 col-md-3" v-if="form.collectcate.cate.collect_part === 'score'"/>

          <div class="col-12 row">
            <q-uploader
              style="max-width: 100%"
              label="选择材料进行上传"
              multiple
              accept=".jpg, image/*"
              @rejected="onRejected"
              class="col-12 col-md-3"
              method="PUT"
              send-raw
              :factory="uploadFactoryFn"
            />
            <div class="q-ma-md text-caption col-12 col-md-3">
              <div>上传注意</div>
                <ul>
                  <li>可同时上传多份材料图片</li>
                  <li>全部添加完毕后必须点击右上角的“上传”按钮</li>
                  <li>务必上传证书扫描件，否则可能审核失败</li>
                </ul>
              </div>
            </div>
          </q-form>
        <q-stepper-navigation>
          <q-btn @click="validate(1, 2)" color="primary" type="submit" label="下一步" />
        </q-stepper-navigation>
      </q-step>

      <q-step
        :name="2"
        title="添加成员并设定参与度"
        icon="create_new_folder"
        :done="step > 2"
      >
        <div class="" style="max-width: 350px">
          <!-- 这里是列表，那么我们应该根据限制查找对应的人员 -->
          <template v-for="(restrict, idx) in form.collectcate.cate.restricts" :key="idx">
            <div>
              <div> {{ '限制添加人员类型为：' + typeMapper[restrict.restrict_type] }} </div>
              <div> {{ '所在部门为：' + restrict.department.name }} </div>
              <div> {{ '添加最少人数：' + restrict.people_limit_min }} </div>
              <div> {{ '添加最多人数：' + restrict.people_limit_max }} </div>
              <div v-if="restrict.restrict_type === 'joiner'"> {{ '此列表人员需分配整数参与度，和必须是100.' }} </div>
            </div>
            <!-- 人员列表展示 -->
            <q-list bordered>
              <template v-for="(member, idx) in form.people_list[restrict.id]" :key="idx">
                <q-item clickable v-ripple @click="this.restrict = restrict, confirm=true, curClickItem=member">
                  <q-item-section avatar>
                    <y-auto-head-icon :user="member" imgBase="test/" />
                  </q-item-section>
                  <q-item-section>
                    <div>{{member.uid}}-{{member.name}}</div>
                    <div class="text-caption">{{restrict.restrict_type === 'joiner' && member.play_role_imp ? '参与度:' + member.play_role_imp : ''}}</div>
                  </q-item-section>
                </q-item>
                <q-separator />
              </template>

              <q-item clickable v-ripple v-if="form.people_list[restrict.id].length < restrict.people_limit_max" @click="prompt = true, this.restrict = restrict">
                <q-item-section avatar>
                  <q-avatar color="teal" text-color="white" icon="add" />
                </q-item-section>

                <q-item-section>添加成员</q-item-section>
              </q-item>

            </q-list>

          </template>
              <!-- 操作提示 -->
              <q-dialog v-model="confirm" persistent>
                <q-card>
                  <q-card-section class="row items-center">
                    <q-avatar icon="priority_high" size=32px color="primary" text-color="white" />
                    <span class="q-ml-sm">请选择要进行的操作</span>
                  </q-card-section>

                  <q-card-actions align="right">
                    <q-btn flat label="取消" color="primary" v-close-popup />
                    <q-btn flat v-if="restrict.restrict_type === 'joiner'" label="修改参与度" color="primary" v-close-popup @click="addJob=true" />
                    <q-btn flat label="删除成员" color="primary" v-close-popup v-if="curClickItem !== 0" @click="removeStu" />
                  </q-card-actions>
                </q-card>
              </q-dialog>
              <!-- 操作提示 -->

              <!-- 添加成员 -->
              <q-dialog v-model="prompt" persistent>
                <q-card style="min-width: 350px">
                  <q-card-section>
                    <div class="text-h6">人员工号</div>
                  </q-card-section>

                  <q-card-section class="q-pt-none">
                    <!-- 现在我们要获取这个内容然后调用一个方法添加 -->
                    <q-input dense autofocus v-model="searchID" @keyup.enter="prompt = false, searchAndAddStudent()" />
                  </q-card-section>

                  <q-card-actions align="right" class="text-primary">
                    <q-btn flat label="取消" v-close-popup />
                    <q-btn flat label="尝试查找并添加" @click="searchAndAddStudent()" v-close-popup />
                  </q-card-actions>
                </q-card>
              </q-dialog>
              <!-- 添加队员 -->

              <!-- 添加参与度 -->
              <q-dialog v-model="addJob" persistent>
                <q-card style="min-width: 350px">
                  <q-card-section>
                    <div class="text-h6">参与度设定</div>
                  </q-card-section>

                  <q-card-section class="q-pt-none">
                    <!-- 现在我们要获取这个内容然后调用一个方法添加 -->
                    <q-input dense autofocus v-model="currentJob" @:rules="[val => val >= 0 && val <= 100]" keyup.enter="addJob = false, formInsertJob()" />
                  </q-card-section>

                  <q-card-actions align="right" class="text-primary">
                    <q-btn flat label="取消" v-close-popup />
                    <q-btn flat label="添加参与度" @click="formInsertJob" v-close-popup />
                  </q-card-actions>
                </q-card>
              </q-dialog>
              <!-- 添加工作 -->

        </div>
        <q-stepper-navigation>
          <q-btn @click="validate(2, 3)" color="primary" label="下一步" />
        </q-stepper-navigation>
      </q-step>

      <q-step
        :name="3"
        title="完成"
        icon="add_comment"
      >
      <div>请仔细核实信息是否有误。</div>
      <div>提交审核后申请无法撤回！确定要提交审核吗？</div>

        <q-stepper-navigation>
          <q-btn color="primary" label="提交审核" @click="submitForm" />
          <q-btn flat @click="step = 2" color="primary" label="返回" class="q-ml-sm" />
        </q-stepper-navigation>
      </q-step>
    </q-stepper>
  </div>
  </q-page>
</template>

<script>
import { ref } from 'vue'
import { Notify, useQuasar } from 'quasar'
import { mapGetters } from 'vuex'
import yAutoHeadIcon from 'src/components/y-auto-head-icon.vue'

const typeMapper = {
  joiner: '竞赛参与者',
  advisor: '指导者',
  checker: '外部审批者'
}

export default {
  components: { yAutoHeadIcon },
  data () {
    const $q = useQuasar()

    function onRejected (rejectedEntries) {
      $q.notify({
        type: 'negative',
        message: `${rejectedEntries.length}个文件格式不受支持`
      })
    }
    return {
      typeMapper,
      step: ref(1),
      onRejected,
      confirm: ref(false),
      prompt: ref(false),
      restrict: null,
      form: {
        collectcate: ref({
          pk: null,
          cate: {
            id: null,
            levels: [],
            collect_part: '',
            name: '',
            restricts: []
          }
        }),
        achieved_date: ref(null),
        people_list: {},
        level: ref({
          pk: null,
          name: ''
        }),
        name: null,
        score: null
      },
      options: ref([]),
      fileList: [],

      searchID: '', // 用于查找用户
      curClickItem: ref(null), // 用于指定是哪个用户
      addJob: false, // 设置添加窗体
      currentJob: ref(null), // 当前用户添加的具体工作
      curTeacherName: ''
    }
  },
  created () {
    // 获取竞赛类目
    // if (!this.isLogined) {
    //   this.$router.replace('/')
    // }
    this.$store.dispatch('comp/getCateList')
      .catch(error => {
        Notify.create({
          type: 'negative',
          message: '获取竞赛类目失败。原因：' + error + '：' + error.response.data
        })
      })
  },
  watch: {
    // 用于清空表单
    'form.collectcate': function (newVal, oldVal) {
      this.form.people_list = {}
      const peopleList = this.form.people_list
      newVal.cate.restricts.forEach(o => {
        peopleList[o.id] = []
      })
    }
  },
  computed: {
    ...mapGetters('comp', [
      'getCateList'
    ]),
    ...mapGetters('session', [
      'getUser',
      'isLogined'
    ])
  },
  methods: {
    filterFn (val, update) {
      if (val === '') {
        update(() => {
          this.options = this.getCateList
        })
        return
      }

      update(() => {
        const needle = val.toLowerCase()
        this.options = this.getCateList.filter(v => v.cate.name.toLowerCase().indexOf(needle) > -1)
      })
    },

    uploadFactoryFn (files) {
      return new Promise((resolve) => {
        files.forEach(file => {
          const fileName = 'GEEXIN_' + Date.now()
          // 这里我们要换成带认证的请求方式
          this.$store.dispatch('comp/getUploadPresignedURL', fileName)
            .then(url => {
              resolve({
                url: url,
                headers: [{ name: 'Content-Type', value: file.type }]
              })
              return file
            })
            .then((file) => {
              this.fileList.push({ file: file, name: fileName })
            }).catch((e) => {
              Notify.create('文件上传失败！原因：' + e)
            })
        })
      })
    },

    validate (id, nextStep) {
      // 根据不同的id进行不同的表单验证
      let success = true
      let restrictList
      switch (id) {
        case 1:
          this.$refs.form1.validate().then(success => {
            // 我们还要检查是否所有文件都上传上去了 同时还需要一个变量保存上传的文件名
            if (this.fileList.length === 0) {
              Notify.create('未添加图片材料，请检查是否上传成功')
              success = false
            }
            if (success) {
              this.step = nextStep
            }
          })
          break
        case 2:
          restrictList = this.form.collectcate.cate.restricts
          console.log('?', restrictList)
          // 检查每一个列表的填写情况 如果是joiner则需要检查参与度的和
          for (let i = 0; i < restrictList.length; i += 1) {
            const restrict = restrictList[i]
            const restrictLi = this.form.people_list[restrict.id]
            const len = restrictLi.length
            if (len >= restrict.people_limit_min && len <= restrict.people_limit_max) {
              if (restrict.restrict_type === 'joiner') {
                let sum = 0
                restrictLi.forEach(p => {
                  const imp = p.play_role_imp | 0
                  sum += imp
                })
                console.log('sum', sum)
                if (sum !== 100) {
                  success = false
                  Notify.create(`请检查：第${i + 1}个列表人员的参与度之和必须为100`)
                }
              } else {
                // 其他不需要检查了
              }
            } else {
              Notify.create(`请检查：第${i + 1}个列表人员数量不符合要求`)
              success = false
            }
          }
          if (success) {
            this.step = nextStep
          }
          break
      }
    },

    searchAndAddStudent () {
      // 查找学生，得到对象之后将其加入到list当中去
      this.$store.dispatch('comp/searchUserInfo', this.searchID)
        .then(stu => {
          // 这里要检查是否符合要求 如果不符合 就要出错
          console.log('searchAndAddStudent', this.restrict, stu)
          if (this.restrict.department.pk !== stu.department) {
            Notify.create('所添加人员归属部门错误！')
            return
          }
          stu.restrict = this.restrict.id
          stu.play_role_imp = 0
          this.form.people_list[this.restrict.id].push(stu)
          this.searchID = ''
        })
        .catch(error => {
          Notify.create('无法获取人员信息，原因：' + error + '：' + error.response.data)
        })
      this.searchID = ''
    },

    formInsertJob () {
      // 我们要找到这个对象 然后把参与度更新上去
      // this.form.team[this.curClickItem].job = this.currentJob
      this.curClickItem.play_role_imp = this.currentJob
    },

    removeStu () {
      console.log(this.curClickItem, this.form.people_list[this.restrict.id], this.restrict)
      this.form.people_list[this.restrict.id].pop(this.curClickItem)
    },

    submitForm () {
      console.log('submitForm', this.form)
      const form = this.form
      let joinList = []
      for (const restrict in form.collectcate.cate.restricts) {
        joinList = joinList.concat(form.people_list[form.collectcate.cate.restricts[restrict].id])
      }
      const nForm = {
        cate: form.collectcate.pk,
        name: form.name ? form.name : '',
        level: form.level.pk,
        score: form.score | 0,
        achieved_date: form.date.replaceAll('/', '-'),
        pics: this.fileList.map(o => { return { name: o.name } }),
        join_list: joinList
      }
      console.log('submit', nForm)
      this.$store.dispatch('comp/submitCompRequest', nForm) // 需要设计
        .then((msg) => {
          Notify.create('提交成功！你也需要同意自己的请求哦')
          this.$router.replace('msgbox')
        })
        .catch(error => {
          Notify.create('提交失败！原因：' + error.response.data)
        })
    }
  }
}
</script>
